/// 通用API响应模型
/// 
/// 用于封装所有API接口返回的统一响应格式
/// 支持泛型，可以包装任何类型的数据
class ApiResponse<T> {
  /// 响应状态码
  final int code;
  
  /// 响应消息
  final String? msg;
  
  /// 响应数据
  final T? data;

  const ApiResponse({
    required this.code,
    this.msg,
    this.data,
  });

  /// 从 JSON 创建 ApiResponse 对象
  /// 
  /// [fromJsonT] 是将 data 部分的 JSON 转换为 T 类型的函数
  /// 如果不提供 [fromJsonT]，data 将保持为动态类型
  factory ApiResponse.fromJson(
    Map<String, dynamic> json, {
    T Function(Map<String, dynamic>)? fromJsonT,
  }) {
    try {
      dynamic dataValue = json['data'];
      T? typedData;
      
      if (dataValue != null && fromJsonT != null) {
        if (dataValue is Map<String, dynamic>) {
          typedData = fromJsonT(dataValue);
        } else {
          // 如果data不是Map，直接转换
          typedData = dataValue as T?;
        }
      } else {
        typedData = dataValue as T?;
      }

      return ApiResponse<T>(
        code: json['code']?.toInt() ?? 0,
        msg: json['msg']?.toString(),
        data: typedData,
      );
    } catch (e) {
      print('ApiResponse.fromJson解析错误: $e');
      print('原始数据: $json');
      
      // 返回错误响应而不是抛出异常
      return ApiResponse<T>(
        code: 500,
        msg: '数据解析失败: $e',
        data: null,
      );
    }
  }

  /// 转换为 JSON 格式
  Map<String, dynamic> toJson({
    Map<String, dynamic> Function(T)? toJsonT,
  }) {
    dynamic dataValue = data;
    
    if (data != null && toJsonT != null) {
      dataValue = toJsonT(data as T);
    } else if (data != null && data is Map<String, dynamic>) {
      dataValue = data;
    } else if (data != null) {
      // 尝试调用对象的toJson方法
      try {
        final dynamic obj = data;
        if (obj != null && obj.runtimeType.toString().contains('toJson')) {
          dataValue = (obj as dynamic).toJson();
        }
      } catch (e) {
        // 如果转换失败，保持原值
        dataValue = data;
      }
    }

    return {
      'code': code,
      'msg': msg,
      'data': dataValue,
    };
  }

  /// 创建副本，支持部分字段更新
  ApiResponse<T> copyWith({
    int? code,
    String? msg,
    T? data,
  }) {
    return ApiResponse<T>(
      code: code ?? this.code,
      msg: msg ?? this.msg,
      data: data ?? this.data,
    );
  }

  /// 判断请求是否成功
  bool get isSuccess => code == 200;

  /// 判断请求是否失败
  bool get isFailure => !isSuccess;

  /// 获取错误信息
  String get errorMessage {
    if (isSuccess) return '';
    
    if (msg != null && msg!.isNotEmpty) {
      return msg!;
    }
    
    // 根据状态码返回默认错误信息
    return _getDefaultErrorMessage(code);
  }

  /// 根据状态码获取默认错误信息
  String _getDefaultErrorMessage(int statusCode) {
    switch (statusCode) {
      case 400:
        return '请求参数错误';
      case 401:
        return '未授权访问';
      case 403:
        return '禁止访问';
      case 404:
        return '资源不存在';
      case 405:
        return '请求方法不允许';
      case 408:
        return '请求超时';
      case 409:
        return '请求冲突';
      case 422:
        return '请求参数验证失败';
      case 429:
        return '请求过于频繁，请稍后重试';
      case 500:
        return '服务器内部错误';
      case 502:
        return '网关错误';
      case 503:
        return '服务不可用';
      case 504:
        return '网关超时';
      default:
        return '请求失败，请重试 (错误码: $statusCode)';
    }
  }

  /// 创建成功响应
  static ApiResponse<T> success<T>(T data, {String? message}) {
    return ApiResponse<T>(
      code: 200,
      msg: message,
      data: data,
    );
  }

  /// 创建错误响应
  static ApiResponse<T> error<T>(int code, {String? message, T? data}) {
    return ApiResponse<T>(
      code: code,
      msg: message,
      data: data,
    );
  }

  /// 将当前响应转换为另一种类型的响应
  ApiResponse<R> cast<R>({
    R Function(T)? converter,
  }) {
    R? newData;
    if (data != null && converter != null) {
      newData = converter(data as T);
    } else {
      newData = data as R?;
    }

    return ApiResponse<R>(
      code: code,
      msg: msg,
      data: newData,
    );
  }

  @override
  String toString() {
    return 'ApiResponse<$T>(code: $code, msg: $msg, data: $data)';
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is ApiResponse<T> &&
        other.code == code &&
        other.msg == msg &&
        other.data == data;
  }

  @override
  int get hashCode => code.hashCode ^ msg.hashCode ^ data.hashCode;
}

/// 用于处理分页数据的响应模型
class PagedApiResponse<T> extends ApiResponse<PagedData<T>> {
  const PagedApiResponse({
    required super.code,
    super.msg,
    super.data,
  });

  /// 从 JSON 创建分页响应对象
  factory PagedApiResponse.fromJson(
    Map<String, dynamic> json, {
    required T Function(Map<String, dynamic>) fromJsonT,
  }) {
    return PagedApiResponse<T>(
      code: json['code']?.toInt() ?? 0,
      msg: json['msg']?.toString(),
      data: json['data'] != null
          ? PagedData<T>.fromJson(
              json['data'] as Map<String, dynamic>,
              fromJsonT: fromJsonT,
            )
          : null,
    );
  }

  /// 获取分页数据列表
  List<T> get items => data?.items ?? [];
  
  /// 获取总数
  int get total => data?.total ?? 0;
  
  /// 获取当前页码
  int get page => data?.page ?? 1;
  
  /// 获取每页数量
  int get pageSize => data?.pageSize ?? 20;
  
  /// 是否有更多数据
  bool get hasMore => data?.hasMore ?? false;
}

/// 分页数据模型
class PagedData<T> {
  /// 数据列表
  final List<T> items;
  
  /// 总数
  final int total;
  
  /// 当前页码
  final int page;
  
  /// 每页数量
  final int pageSize;

  const PagedData({
    required this.items,
    required this.total,
    required this.page,
    required this.pageSize,
  });

  /// 从 JSON 创建分页数据对象
  factory PagedData.fromJson(
    Map<String, dynamic> json, {
    required T Function(Map<String, dynamic>) fromJsonT,
  }) {
    final itemsJson = json['items'] as List<dynamic>? ?? [];
    final items = itemsJson
        .map((item) => fromJsonT(item as Map<String, dynamic>))
        .toList();

    return PagedData<T>(
      items: items,
      total: json['total']?.toInt() ?? 0,
      page: json['page']?.toInt() ?? 1,
      pageSize: json['pageSize']?.toInt() ?? 20,
    );
  }

  /// 转换为 JSON 格式
  Map<String, dynamic> toJson({
    Map<String, dynamic> Function(T)? toJsonT,
  }) {
    return {
      'items': items.map((item) {
        if (toJsonT != null) {
          return toJsonT(item);
        } else {
          try {
            return (item as dynamic).toJson();
          } catch (e) {
            return item;
          }
        }
      }).toList(),
      'total': total,
      'page': page,
      'pageSize': pageSize,
    };
  }

  /// 是否有更多数据
  bool get hasMore => page * pageSize < total;

  /// 创建副本
  PagedData<T> copyWith({
    List<T>? items,
    int? total,
    int? page,
    int? pageSize,
  }) {
    return PagedData<T>(
      items: items ?? this.items,
      total: total ?? this.total,
      page: page ?? this.page,
      pageSize: pageSize ?? this.pageSize,
    );
  }

  @override
  String toString() {
    return 'PagedData<$T>(items: ${items.length}, total: $total, page: $page, pageSize: $pageSize)';
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is PagedData<T> &&
        other.items == items &&
        other.total == total &&
        other.page == page &&
        other.pageSize == pageSize;
  }

  @override
  int get hashCode =>
      items.hashCode ^ total.hashCode ^ page.hashCode ^ pageSize.hashCode;
}
